package org.mjl.jackson.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

/**
 * BaiduMapUtil
 *
 * @author mjl
 * @date 2021-04-12
 */
public class BaiduMapUtil {

    /**
     * 百度地图AK-zpc提供
     */
    private static final String BAIDU_MAP_AK = "O38BQVVfbsdMSDr6sEh7qEyFhijhpwa1";


    /**
     * 输入地址返回经纬度
     * https://lbsyun.baidu.com/faq/api?title=webapi/guide/webservice-geocoding-base
     * <p>
     * 注意：当前为V3.0版本接口文档，V2.0及以前版本自2019.6.18起新用户无法使用。
     * 老用户仍可继续使用V2.0及以前版本请求实现逆地理编码服务，为保障用户体验，建议您尽快迁移到V3.0版本。
     * http://api.map.baidu.com/geocoding/v3/?address=北京市海淀区上地十街10号&output=json&ak=您的ak&callback=showLocation //GET请求
     * 参数名	参数含义    类型	    举例	                    默认值	                  是否必须
     * address        string	北京市海淀区上地十街10号	无	                      是
     * city           string	北京市	                无                        否
     * ret_coordtype  string	gcj02ll（国测局坐标）、
     * bd09mc（百度墨卡托坐标）	bd09ll（百度经纬度坐标）	  否
     * ak             string	                        无	                      是
     * output         string	json或xml	            json                      否
     * callback	      string		                    无	                      否
     * <p>
     * 返回结果：
     * {
     * "status": 0,
     * "result": {
     * "location": {
     * "lng": 116.3084202915042,
     * "lat": 40.05703033345938
     * },
     * "precise": 1,
     * "confidence": 80,
     * "comprehension": 100,
     * "level": "门址"
     * }
     * }
     * status
     * 返回结果状态值， 成功返回0，其他值请查看下方返回码状态表。	int
     */
    private static final String BAIDU_MAP_GEO_API = "http://api.map.baidu.com/geocoding/v3/";
    private static ObjectMapper objectMapper = new ObjectMapper();


    public BaiduMapUtil() {
    }

    public static Map<String, String> getLonlat(String address) {
        Map<String, String> resultMap = new HashMap<>();

        String url = BAIDU_MAP_GEO_API + "?output=json&ak=" + BAIDU_MAP_AK + "&address=" + address;
        try {
            RestTemplate restTemplate = new RestTemplate();

            String object = restTemplate.getForObject(url, String.class);
            Map map = objectMapper.readValue(object, Map.class);
            String status = String.valueOf(map.get("status"));
            if ("0".equals(status)) {
                Map<String, Object> result = (Map<String, Object>) map.get("result");
                Map<String, Object> location = (Map<String, Object>) result.get("location");
                String lng = String.valueOf(location.get("lng"));
                String lat = String.valueOf(location.get("lat"));
                resultMap.put("lon", lng);
                resultMap.put("lat", lat);
                resultMap.put("lonlat", lng + "," + lat);
            }
            resultMap.put("msg", statusCode(status));
            return resultMap;
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    private static final Map<String,String> STATUS_CODE_MAP = new HashMap<>();

    static {
        STATUS_CODE_MAP.put("0","正常");
        STATUS_CODE_MAP.put("1","服务器内部错误");
        STATUS_CODE_MAP.put("2","请求参数非法\t必要参数拼写错误或漏传（如query和tag请求中均未传入）");
        STATUS_CODE_MAP.put("3","权限校验失败\t服务请求正常召回");
        STATUS_CODE_MAP.put("4","配额校验失败\t服务当日调用次数已超限，请前往API控制台提升（请优先进行开发者认证）");
        STATUS_CODE_MAP.put("5","ak不存在或者非法\t未传入ak参数；ak已被删除（可前往回收站恢复）");
        STATUS_CODE_MAP.put("101","AK参数不存在\t请求消息没有携带AK参数");
        STATUS_CODE_MAP.put("102","不通过白名单或者安全码不对");
        STATUS_CODE_MAP.put("240","APP 服务被禁用\t用户在API控制台中创建或设置某APP的时候禁用了某项服务，若需开通权限，可进入API控制台为AK勾选对应服务");
        STATUS_CODE_MAP.put("2xx","无权限");
        STATUS_CODE_MAP.put("3xx","配额错误");
    }

    private static String statusCode(String status) {
        String result = STATUS_CODE_MAP.get(status);
        return result;
    }

    public static void main(String[] args) {
        System.out.println(getLonlat("北京市海淀区彩和坊路海淀西大街74号"));
    }
}
